package com.gopay.bis.manager.bank.ebank;

import java.io.UnsupportedEncodingException;
import java.util.Map;

import javax.annotation.Resource;

import org.apache.commons.lang3.StringUtils;

import com.gopay.bis.common.util.BankLogUtils;
import com.gopay.bis.common.util.TransUtil;
import com.gopay.common.Result;
import com.gopay.common.constants.bank.BankConstants;
import com.gopay.common.constants.proccode.ProcCodeConstants;
import com.gopay.common.domain.bank.BaseMessage;
import com.gopay.common.domain.bank.spdb.ebank.SpdbMessage;
import com.gopay.common.domain.user.mcc.UserMccTransformReq;
import com.gopay.common.domain.user.mcc.UserMccTransformRes;
import com.gopay.common.exception.GopayException;
import com.gopay.common.user.mcc.manager.UserMccTransformManager;
import com.gopay.remote.bank.BankManagerRemoteService;
import com.gopay.remote.bank.businesses.BankService;

/**
 * @SpdbB2cManager.java
 * @author wanggang
 * @2013-12-12 下午1:49:13 www.gopay.com.cn Inc.All rights reserved.
 */
public class SpdbB2cManager implements BankManagerRemoteService {

	@Resource(name = "spdbConfig")
	private Map<String, String> spdbConfig;
	
	@Resource(name = "bisConfig")
    private Map<String, String> bisConfig;
	
	@Resource(name = "spdbB2cBankServiceClientHna")
	private BankService spdbB2cBankServiceClientHna;
	
	@Resource(name = "spdbB2cBankServiceClient")
	private BankService spdbB2cBankServiceClient;
	
	@Resource(name = "userMccTransformManager")
    private UserMccTransformManager userMccTransformManager;

	@Override
	public Object sign(BaseMessage msg) throws GopayException {
		SpdbMessage message = (SpdbMessage) msg;
		message.setBankOrderId(TransUtil.processOrderIdTo12Digit(msg.getOrderId()));
		message.setBankUrl(message.getPayUrl());
		message.setTermCode((String) spdbConfig.get("SPDB.TERMCODE"));
		message.setMercCode(message.getMerID());
		message.setMercUrl(message.getPayRuturnUrl());
		message.setTranAbbr((String) spdbConfig.get("SPDB.B2C.TRANABBR"));
		message.setIp((String) spdbConfig.get("SPDB.B2C.IP"));
        // 二级商户号报备
        UserMccTransformReq userM = new UserMccTransformReq();
        userM.setBankCode(BankConstants.BANK_LOGO_SPDB);
        userM.setCustId(msg.getSpecial2());
        UserMccTransformRes userRes = userMccTransformManager.graspUserMccInfo(userM);

        if (userRes == null) {
            if ((BankConstants.GOPAY_CHONGZHI_CUSTID).equals(msg.getSpecial2())) {
                message.setSubMercFlag((String) spdbConfig.get("SPDB.SUBMERC.XUNI"));
                message.setSubMercName(BankConstants.GOPAY_NAME);
                message.setSubMercGoodsName("国付宝充值");
            }
        } else {
            // p2p商户上送mcc处理
            if (BankConstants.GOPAY_MCC_CODE.equals(userRes.getGopayMccCode())) {
//                String gopayCustIds = (String) bisConfig.get("GOPAY.MCC.CUSTID");
//                String[] gopayCustIdArray = gopayCustIds.split(",");
//                Random rand = new Random();
//                int num = rand.nextInt(gopayCustIdArray.length);
//                String custId = new String(gopayCustIdArray[num]);
//                UserMccTransformReq userReq = new UserMccTransformReq();
//                userReq.setBankCode(BankConstants.BANK_LOGO_SPDB);
//                userReq.setCustId(custId);
//                System.out.println("spdb b2c update mercode: " + custId);
//                message.setSendBankCustId(custId);
//                UserMccTransformRes res = userMccTransformManager.graspUserMccInfo(userReq);
//                if (res == null) {
//                    // 若随机取出商户信息为空, 上送国付宝测试账户信息
//                    message.setSendBankCustId("0000000363");
//                    res = new UserMccTransformRes();
//                    res.setCorpName(BankConstants.GOPAY_NAME);
//                    res.setBankMccCode(BankConstants.BANK_MCC_CODE_4816);
//                    res.setBankMccDesc("计算机网络/信息服务");
//                }
//                System.out.println("spdb b2c update mcc message: " + ToStringBuilder.reflectionToString(res));
                message.setSubMercFlag((String) spdbConfig.get("SPDB.SUBMERC.SHIWU"));
//                message.setSubMercName(res.getCorpName());
//                message.setSubMercGoodsName(res.getBankMccDesc());
                // 浦发P2P商户报备信息固定, 商户名称上送空格商品信息上送"信息服务"
                message.setSubMercName("（");
                message.setSubMercGoodsName("平台服务）");
                
//                if (BankConstants.BANK_MCC_CODE_7375.equals(res.getBankMccCode())
//                        || BankConstants.BANK_MCC_CODE_4814.equals(res.getBankMccCode())
//                        || BankConstants.BANK_MCC_CODE_4816.equals(res.getBankMccCode())) {
//                    // 信息检索服务、计算机网络、电信服务归属于消费虚拟类
//                    message.setSubMercFlag((String) spdbConfig.get("SPDB.SUBMERC.XUNI"));
//                }
            } else {
                // 非p2p商户信息报备
                message.setSubMercFlag((String) spdbConfig.get("SPDB.SUBMERC.SHIWU"));
                message.setSubMercName(userRes.getCorpName());
                message.setSubMercGoodsName(userRes.getBankMccDesc());
                if (BankConstants.BANK_MCC_CODE_7375.equals(userRes.getBankMccCode())
                        || BankConstants.BANK_MCC_CODE_4814.equals(userRes.getBankMccCode())
                        || BankConstants.BANK_MCC_CODE_4816.equals(userRes.getBankMccCode())) {
                    // 信息检索服务、计算机网络、电信服务归属于消费虚拟类
                    message.setSubMercFlag((String) spdbConfig.get("SPDB.SUBMERC.XUNI"));
                }
            }
        }
        
		String plainMessage = buildMessage(message);
		message.setPlainMessage(plainMessage);
		BankLogUtils.printB2CManagerSignSendLog(message);
		String signMessage;
		if(message.isHna()){
			signMessage = (String) this.spdbB2cBankServiceClientHna.sign(message);
		}else{
			signMessage = (String) this.spdbB2cBankServiceClient.sign(message);
		}
		message.setSignMessage(signMessage);
		BankLogUtils.printB2CManagerSignReturnLog(message);
		return message;
	}

	@Override
	public Object verify(BaseMessage baseMessage) throws GopayException {
		SpdbMessage message = (SpdbMessage) baseMessage;
		BankLogUtils.printB2CVerifyPlainLog(baseMessage);
		BankLogUtils.printB2CVerifySignatureLog(baseMessage, message.getSignMessage());
		boolean isVerify;
		if(message.isHna()){
			isVerify = (Boolean) this.spdbB2cBankServiceClientHna.verify(message);
		}else{
			isVerify = (Boolean) this.spdbB2cBankServiceClient.verify(message);
		}
		BankLogUtils.printB2CVerifyResultLog(baseMessage, isVerify);
		return isVerify;
	}

	@Override
	public Object query(Object obj) throws GopayException {
		SpdbMessage message = (SpdbMessage) obj;
		message.setTermCode((String) spdbConfig.get("SPDB.TERMCODE"));
		message.setMercCode((String) spdbConfig.get("SPDB.B2C.MERCCODE"));
		message.setTransName((String) spdbConfig.get("SPDB.TRANABBR.QUERY"));
		message.setoTranAbbr((String) spdbConfig.get("SPDB.B2C.TRANABBR"));
		message.setTermSsn(message.getBankOrderId());
		message.setPlainMessage(buildQuery(message));
		BankLogUtils.printB2CManagerQuerySendLog(message, "");
		if(message.isHna()){
			message = (SpdbMessage) this.spdbB2cBankServiceClientHna.query(message);
		}else{
			message = (SpdbMessage) this.spdbB2cBankServiceClient.query(message);
		}
		BankLogUtils.printB2CManagerQueryReturnLog(message);
		return message;
	}

	/**
	 * 构建报文
	 * 
	 * @param message
	 * @return
	 * @throws GopayException 
	 */
	private String buildMessage(SpdbMessage message) throws GopayException {
		// 组织明文串
	    StringBuffer sb = new StringBuffer();
		try {
	        sb.append("TranAbbr=").append(message.getTranAbbr()).append("|");
	        sb.append("MercDtTm=").append(message.getOrderDate()).append("|");
	        sb.append("TermSsn=").append(message.getBankOrderId()).append("|");
	        sb.append("OSttDate=").append(message.getoSttDate()).append("|");
	        sb.append("OAcqSsn=").append(message.getoAcqSsn()).append("|");
	        sb.append("MercCode=").append(message.getMercCode()).append("|");
	        sb.append("TermCode=").append(message.getTermCode()).append("|");
	        sb.append("TranAmt=").append(message.getAmount().toString()).append("|");
	        sb.append("Remark1=").append(message.getRemark1()).append("|");
	        sb.append("Remark2=").append(message.getRemark2()).append("|");
	        sb.append("MercUrl=").append(message.getMercUrl()).append("|");
	        sb.append("Ip=").append(message.getIp()).append("|");
	        sb.append("SubMercFlag=").append(message.getSubMercFlag()).append("|");
            if (StringUtils.isBlank(message.getSubMercName())) {
                sb.append("SubMercName=").append(message.getSubMercName()).append("|");
            } else {
                sb.append("SubMercName=").append(java.net.URLEncoder.encode(message.getSubMercName(), "GBK")).append("|");
            }
            if (StringUtils.isBlank(message.getSubMercGoodsName())) {
                sb.append("SubMercGoodsName=").append(message.getSubMercGoodsName()).append("|");
            } else {
                sb.append("SubMercGoodsName=").append(java.net.URLEncoder.encode(message.getSubMercGoodsName(),"GBK")).append("|");
            }
            
            sb.append("PayFlag=").append(message.getPayFlag());
        } catch (UnsupportedEncodingException e) {
            BankLogUtils.printB2CSignExceptionLog(message, e);
            throw new GopayException(ProcCodeConstants.PROC_CODE_100E6029);
        }
		return sb.toString();
	}

	private String buildQuery(SpdbMessage message) {
		StringBuffer sb = new StringBuffer();
		sb.append("MercCode=").append(message.getMercCode()).append("|");
		sb.append("OTranAbbr=").append(message.getoTranAbbr()).append("|");
		sb.append("TermSsn=").append(message.getBankOrderId());
		return sb.toString();
	}

	@Override
	public Object dayend(BaseMessage base) throws GopayException, Exception {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public Object refund(BaseMessage base) throws GopayException {
		// TODO Auto-generated method stub
		return null;
	}
}
